﻿using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
using XTemplate.Base.Model;
using XTemplate.Repository;

namespace XTemplate.Base.Respository
{
    public class TableGeneratorRepository : ModelRepositoryBase
    {
        public override MyDbContext DbContext { get; }

        public override ILogger Logger { get; }

        public TableGeneratorRepository(MyDbContext dbContext, ILogger<TableGeneratorRepository> log)
        {
            DbContext = dbContext;
            Logger = log;
        }

        /// <summary>
        /// 2020.05.17增加mysql获取表结构时区分当前所在数据库
        /// </summary>
        /// <returns></returns>
        private string GetMysqlTableSchema(string tableSchema = "")
        {
            try
            {
                string schemaWhere = " and table_schema = '{0}' ";
                if (!string.IsNullOrEmpty(tableSchema))
                    return string.Format(schemaWhere, tableSchema);

                string dbName = DbContext.Database.GetDbConnection().ConnectionString.Split(new string[] { "Database=", "database=", "DATABASE=" }, StringSplitOptions.RemoveEmptyEntries)[1].Split(";")[0]?.Trim();
                if (!string.IsNullOrEmpty(dbName))
                {
                    return string.Format(schemaWhere, dbName);
                }
                return dbName;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"获取mysql数据库名异常:{ex.Message}");
                return "";
            }
        }

        public IQueryable<TableInfoModel> GetTableInfo(string tableSchema)
        {
            return this.GetList<TableInfoModel>($@"
					select table_catalog TableCataLog,
						table_schema TableSchema,
						table_name TableName,
						table_type TableType,
						engine Engine,
						table_collation TableCollation,
						row_format RowFormat
					from information_schema.tables
					where table_schema='{tableSchema}'
				");
        }

        public IQueryable<TableColumnInfoModel> GetTableColumnInfo(string tableName, string tableSchema = "")
        {
            return this.GetList<TableColumnInfoModel>(
                $@"
					SELECT DISTINCT
						COLUMN_NAME AS ColumnName,
						TABLE_NAME AS tableName,
						COLUMN_COMMENT AS ColumnCnName,
						CASE
							WHEN data_type IN ( 'BIT', 'BOOL', 'bit', 'bool' ) THEN
							'bool'
							WHEN data_type IN ( 'smallint', 'SMALLINT' ) THEN
							'short'
							WHEN data_type IN ( 'tinyint', 'TINYINT' ) THEN
							'sbyte'
							WHEN data_type IN ( 'MEDIUMINT', 'mediumint', 'int', 'INT', 'year', 'Year' ) THEN
							'int'
							WHEN data_type IN ( 'BIGINT', 'bigint' ) THEN
							'long'
							WHEN data_type IN ( 'FLOAT', 'DOUBLE', 'DECIMAL', 'float', 'double', 'decimal' ) THEN
							'decimal'
							WHEN data_type IN (
								'CHAR',
								'VARCHAR',
								'TINY TEXT',
								'TEXT',
								'MEDIUMTEXT',
								'LONGTEXT',
								'TINYBLOB',
								'BLOB',
								'MEDIUMBLOB',
								'LONGBLOB',
								'Time',
								'char',
								'varchar',
								'tiny text',
								'text',
								'mediumtext',
								'longtext',
								'tinyblob',
								'blob',
								'mediumblob',
								'longblob',
								'time'
								) THEN
								'string'
								WHEN data_type IN ( 'Date', 'DateTime', 'TimeStamp', 'date', 'datetime', 'timestamp' ) THEN
								'DateTime' ELSE 'string'
							END AS ColumnType,
							CONCAT( NUMERIC_PRECISION, ',', NUMERIC_SCALE ) AS PrecScale,
						CASE
							WHEN CHARACTER_MAXIMUM_LENGTH > 8000 THEN
								0 ELSE CHARACTER_MAXIMUM_LENGTH
							END AS Maxlength,
						COLUMN_KEY as ColumnKey,
						COLUMN_DEFAULT as ColumnDefault,
						COLUMN_TYPE as DBColumnType,
						CASE WHEN IS_NULLABLE='YES' THEN true else false END Nullable,
						EXTRA
					FROM
						information_schema.COLUMNS
					WHERE TABLE_NAME = '{tableName}' {GetMysqlTableSchema(tableSchema)}"
                );
        }
    }
}